/*
 * Fichier     : <+NOM_de_FICHIER+>
 * Auteur      : <+MON_NOM+>
 * Version     : <+VERSION_DATE+>
 * Fonction    : <+FONCTION+>
 * Appel       : <+APPEL+>
 * Exit status : <+EXIT+>
 */

#include "analex.h"
#include "func.h"

/*Variables globales*/
char u_lex[256];		// variable contenant le texte correspondant au type token
FILE *f;			// Pointeur sur le fichier pascal
FILE *lst;			// Pointeur sur le fichier .lst
FILE *appel;			// Pointeur sur le fichier texte pour les appels terme() et expression()
FILE *postFix;			// Pointeur sur le fichier postFix
FILE *fpcode;			// Pointeur sur le fichier pcode
int token;			// Jeton utilisé pour connaitre le type
int version=8;			// Version du compilateur
int line=1;			// Compteur de ligne du fichier f géré par analex
struct liste *tableSymbole;	// Création de la table des symbôles
struct pile *pCompilation;	// La pile de compilation
struct pcode *p_code;		// Enregistrement du pcode
struct save_func *sav;

main(int argc, char *argv[])
{
	system("clear");

	/*Quelques variables*/
	char buffer[512], nom[128];
	int ret;

	/*Nombre d'argument*/
	if(argc<2)
	{
		printf("Erreur : veuillez entrer le nom du fichier pascal!\n");
		exit(1);
	}

	printf("##########################################################################################################################\n");
	printf("-------------------------------------------------- Compilateur pascal ----------------------------------------------------\n\n");
	printf("##########################################################################################################################\n");
	printf("Fichier=%s;\nVersion du compilateur=%d;\n\n", argv[1], version);

	/*Ouverture du programme en lecture*/
	f=fopen(argv[1], "r");
	if(f==NULL)
	{
		printf("Erreur : ouverture du fichier %s impossible!\n", argv[1]);
		exit(2);
	}

	/*Redéfini l'entrée standard de analex sur le fichier pascal*/
	yyin=f;

	/*Ouverture du fichier .list en écriture*/
	lst=fopen("listening.lst", "w");

	/*Test de l'ouverture*/
	if(lst==NULL)
	{
		printf("Erreur : ouverture du fichier listening.lst impossible!\n");
		exit(3);
	}

	/*Ecriture de l'entête*/
	sprintf(buffer, "Compiler version v%d\n", version);
	ret=fputs(buffer, lst);

	/*Vérification*/
	if(ret==EOF)
	{
		printf("Erreur : Ecriture de l'entete impossible!\n");
		exit(4);
	}

	/*Ouverture du fichier appel*/
	appel=fopen("appel.aux", "w");

	/*Test de l'ouverture*/
	if(appel==NULL)
	{
		printf("Erreur : ouverture du fichier appel.txt impossible!\n");
		exit(8);
	}

	/*Ouverture du fichier postFix*/
	postFix=fopen("syntax.postfix", "w");

	/*Test de l'ouverture*/
	if(postFix==NULL)
	{
		printf("Erreur : ouverture du fichier syntax.postfix impossible!\n");
		exit(12);
	}

	/*Création de la table des symbôles*/
	tableSymbole=constrListe();

	/*Création de la pile de compilation*/ 
	pCompilation=constrPile();

	/*Création de la structure pcode*/
	p_code=constrPcode();

	/*Création de la structure sav*/
	sav=constrSaveFunc();

	/*Début de l'analyse*/
	print("----------------------------------------------- Resultat de la compilation -----------------------------------------------\n\n");
	ret=program();
	if(ret==0)
	{	
		/*Ecriture de la queue*/
		sprintf(buffer, "\ncompilation reussie!\n");
		ret=fputs(buffer, lst);
		printf("%s\n", buffer);

		/*Vérification*/
		if(ret==EOF)
		{
			 printf("Erreur : Ecriture de la queue impossible!\n");
			 exit(5);
		}
	}
	else
	{
		char code[124];
		display(ret, code);

		sprintf(buffer, "\nEchec de la compilation! \nErreur à la ligne %d. \nCode d'erreur: %s\n", line, code);
		fputs(buffer, lst);
		printf("%s\n", buffer);
	}

	/*Affichage de la table des symbôles*/
	print("-------------------------------------------------- Table des symboles ----------------------------------------------------\n");
	printSymbole(tableSymbole); 
	print("--------------------------------------------------------------------------------------------------------------------------\n");

	/*Affichage de la table des symbôles*/
	print("-------------------------------------------------- Pile de compilation ---------------------------------------------------\n");
	printPile(pCompilation);
	print("--------------------------------------------------------------------------------------------------------------------------\n");

	/*Ouverture du fichier pcode*/
	sprintf(nom, "%scode", argv[1]);
	fpcode=fopen(nom, "w");
	savePcode(p_code, fpcode);
	saveListe(tableSymbole, fpcode);
	affichagePcode(p_code);

	/*Libération de la mémoire*/
	nettoyerListe(tableSymbole);
	nettoyerPile(pCompilation);
	nettoyerPcode(p_code);
	nettoyerSaveFunc(sav);

	/*Fermeture des differents fichiers*/
	fclose(postFix);
	fclose(appel);
	fclose(fpcode);

	printf("Fait!\n");
	exit(0);
}


